/*
 * MIT License
 *
 * Copyright (c) 2023 北京凯特伟业科技有限公司
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */
package com.je.common.base.result;

import com.alibaba.fastjson2.JSON;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.je.common.base.DynaBean;
import com.je.common.base.spring.SpringContextHolder;
import com.je.common.base.util.FormatDate4Json;
import net.sf.json.JSONObject;
import net.sf.json.JsonConfig;
import net.sf.json.util.CycleDetectionStrategy;

import java.io.IOException;
import java.io.Serializable;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class BaseRespResult<T> implements Serializable {
    private static final long serialVersionUID = -4507574037830481719L;

    private static final String OK_CODE = "1000";
    private static final String OK_MESSAGE = "操作成功";
    private static ObjectMapper objectMapper = (ObjectMapper) SpringContextHolder.getBean("objectMapper");
    private String code;
    private T data;
    private String message;
    boolean success;

    /**
     * 分页-数据
     */
    private List rows;
    /**
     * 分页-总条数
     */
    private Long totalCount;

    public BaseRespResult() {
    }


    public BaseRespResult(boolean success, T data, String code, String message) {
        this.success = success;
        Object  object = passeResult(data);
        this.data = (T) object;
        this.code = code;
        this.message = message;
    }

    public BaseRespResult(List rows,T data, String message) {
        Map<String,Object> dataMap = new HashMap<>();
        dataMap.put("rows",rows);
        dataMap.put("totalCount",rows.size());

        this.success = true;
        this.code = OK_CODE;
        Object  object = passeResult(dataMap);
        this.data = (T) object;
        this.message = message;
    }

    public BaseRespResult(boolean success, List rows, String code, String message, Long totalCount) {
        this.success = success;
        try {
            List<DynaBean> beans = (List<DynaBean>) rows;
            Map<String,Object> dataMap = new HashMap<>();
            dataMap.put("rows",beans);
            dataMap.put("totalCount",totalCount);
            Object  object = passeResult(dataMap);
            this.data = (T) object;
            //this.rows = values;
        } catch (Exception e) {
            this.rows = rows;
        }
        this.code = code;
        this.message = message;
    }

    public static BaseRespResult errorResult(String data) {
        return errorResult("200", data);
    }

    public static BaseRespResult errorResult(String code, String data) {
        return new BaseRespResult(false, data, code, data);
    }

    public static BaseRespResult errorResult(String code, Object data) {
        if(data instanceof DynaBean){
            data = ((DynaBean) data).getValues();
        }
        return new BaseRespResult(false, data, code, null);
    }

    public static BaseRespResult errorResult(String code, Object data,String message) {
        if(data instanceof DynaBean){
            data = ((DynaBean) data).getValues();
        }
        return new BaseRespResult(false, data, code, message);
    }

    public static BaseRespResult successResult(Object data) {
        if(data instanceof DynaBean){
            data = ((DynaBean) data).getValues();
        }
        return new BaseRespResult(true, data, OK_CODE, OK_MESSAGE);
    }

    public static BaseRespResult successResult(Object data, String message) {
        if(data instanceof DynaBean){
            data = ((DynaBean) data).getValues();
        }
        return new BaseRespResult(true, data, OK_CODE, message);
    }

    public static BaseRespResult successResult(Object data, String code, String message) {
        if(data instanceof DynaBean){
            data = ((DynaBean) data).getValues();
        }
        return new BaseRespResult(true, data, code, message);
    }

    public static BaseRespResult successResultPage(List rows, Long totalCount) {
        return new BaseRespResult(true, rows, OK_CODE, OK_MESSAGE, totalCount);
    }

    public static BaseRespResult successResultPage(List rows, Long totalCount,String[] excludes) {
        if (rows == null || rows.isEmpty() || excludes == null) {
            return new BaseRespResult(true, rows, OK_CODE, OK_MESSAGE, totalCount);
        }

        List<Object> result = Lists.newArrayList();
        for (Object each: rows) {
            JsonConfig cfg = FormatDate4Json.getCfgByYYYYMMDD();
            cfg.setCycleDetectionStrategy(CycleDetectionStrategy.LENIENT);
            if (null != excludes) {
                cfg.setExcludes(excludes);
            }
            JSONObject jsonObject = JSONObject.fromObject(each, cfg);
            result.add(jsonObject);
        }
        return new BaseRespResult(true, result, OK_CODE, OK_MESSAGE, totalCount);
    }

    /**
     * todo 添加 DynaBean 返回  huxuanhua
     *
     * @param dynaBean
     * @return
     */
    public static BaseRespResult successResult(DynaBean dynaBean) {
        Map resultMap;
        if (null != dynaBean && null != dynaBean.getValues()) {
            resultMap = dynaBean.getValues();
        } else {
            resultMap = Maps.newHashMap();
        }
        return successResult(resultMap);
    }

    private static Object passeResult(Object result) {
        Object response = null;
        if (result == null){
            return response;
        }
        String json = "";
        try {
            json = objectMapper.writeValueAsString(result);
            response = objectMapper.readValue(json, result.getClass());
        } catch (IOException e) {
            response = result;
        }
        return response;
    }
    public boolean getSuccess() {
        return success;
    }

    public void setSuccess(boolean success) {
        this.success = success;
    }

    public String getCode() {
        return code;
    }

    public void setCode(String code) {
        this.code = code;
    }

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }

    public T getData() {
        return data;
    }

    public void setData(T data) {
        this.data = data;
    }

    public List getRows() {
        return rows;
    }

    public void setRows(List rows) {
        this.rows = rows;
    }

    public Long getTotalCount() {
        return totalCount;
    }

    public void setTotalCount(Long totalCount) {
        this.totalCount = totalCount;
    }

    @Override
    public String toString() {
        return JSON.toJSONString(this);
    }
}
